# 1 "fat.c"
# 1 "/home/diego/sodium/fs//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "fat.c"







# 1 "../include/fs/fat.h" 1



# 1 "../include/kernel/definiciones.h" 1
# 14 "../include/kernel/definiciones.h"
# 1 "../include/usr/tipos.h" 1
# 15 "../include/usr/tipos.h"
typedef unsigned int dword;
typedef unsigned short word;
typedef unsigned char byte;

typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;


typedef struct _u80 { unsigned int word[20]; } u80;
# 15 "../include/kernel/definiciones.h" 2
# 62 "../include/kernel/definiciones.h"
char stArgAux[128];
# 5 "../include/fs/fat.h" 2

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
# 35 "../include/fs/fat.h"
typedef uint16_t (*pFatXConst)( uint16_t constant );




typedef uint16_t (*pFatXGetNextCluster)( uint8_t *fat, uint16_t cluster );

typedef uint16_t (*pFatXSetNextCluster)( uint8_t *fat, uint16_t cluster,uint16_t next );
# 129 "../include/fs/fat.h"
typedef struct stuFsEncabezadoFAT {
  uint8_t ignored[ 3 ];
  uint8_t oem_id[ 8 ];
 uint16_t bytes_per_sector;
  uint8_t sectors_per_cluster;
 uint16_t reserved_sectors;
  uint8_t fats;
 uint16_t root_entries;
 uint16_t small_sectors;
  uint8_t media_descriptor;
 uint16_t sectors_per_fat;
 uint16_t sectors_per_track;
 uint16_t heads;
 uint32_t hidden_sectors;
 uint32_t large_sectors;
  uint8_t physical_drive_number;
  uint8_t current_head;
  uint8_t signature;
 uint32_t volume_id;
  uint8_t volume_label[ 11 ];
  uint8_t fs_type[ 8 ];
}stuFsEncabezadoFAT;
# 168 "../include/fs/fat.h"
typedef struct stuFsDirectorioFAT {
  char filename[8];
  char extension[3];
  uint8_t attributes;
  uint8_t reserved;
  uint8_t create_time_fine;
 uint16_t create_time;
 uint16_t create_date;
 uint16_t access_date;
 uint16_t ea_index;
 uint16_t modified_time;
 uint16_t modified_date;
 uint16_t starting_cluster;
 uint32_t filesize;
}stuFsDirectorioFAT;
# 198 "../include/fs/fat.h"
typedef struct stuDeviceHandle {
 int fd;
 uint32_t block_size,
   total_blocks;
}stuDeviceHandle;




typedef struct stuFsHandleFat {
 struct stuDeviceHandle *device;
 struct stuFsEncabezadoFAT *header;
 uint8_t *fat1,
  *fat2,
  *fat3;


 pFatXConst get_constant;
 pFatXGetNextCluster get_next_cluster;
 pFatXSetNextCluster set_next_cluster;
}stuFsHandleFat;
# 231 "../include/fs/fat.h"
typedef struct stuFatSectores {
 byte *sector;
 uint32_t estado;
 struct stuFatSectores *next;
}stuFatSectores;





typedef struct stuSectorBooteo {
    byte jumpBoot[3];
    byte sysName[8];
    word bytesPerSector;
    byte sectorsPerCluster;
    word reservedSectors;
    byte fatCount;
    word maxRootEntries;
    word totalSectors1;
    byte mediaDescriptor;
    word sectorsPerFAT;
    word sectorsPerTrack;
    word headCount;
    dword hiddenSectors;
    dword totalSectors2;
    byte driveNumber;
    byte reserved1;
    byte extBootSignature;
    dword volumeSerial;
    byte volumeLabel[11];
    byte reserved2[8];
}stuSectorBooteo;
# 276 "../include/fs/fat.h"
byte byBufferRead[512];






void vFnIniciarCacheFloppy ();
void vFnLeerArchivo(dword);
void vFnDispLeerArchivo(char *);
int iFnDispEscribirArchivo(char *, char *);



uint16_t t16FnFat12DrvGetConst(uint16_t);
int memcmp(const void *,const void *, dword);
uint16_t t16FnFat12DrvSetNextClust(uint8_t *,uint16_t, uint16_t);
uint16_t t16FnFat12DrvGetNextClust(uint8_t *, uint16_t);
uint8_t* t8FnFatDrvGetClustAddr(uint8_t *, uint16_t);
int iFnIniciarFileSystFloppy();



int iFnObtenerEncabezado();



void vFnMostrarEncabezado();



int iFnIniciarFatDrv ();



int iFnObtenerFat12();



int iFnObtenerCopiaFat12();



uint8_t * t8FnObtenerDirRoot();
# 335 "../include/fs/fat.h"
struct stuFsHandleFat *pstuFsFatHandleHandle;




byte byBuffer[512];


dword dwFnObtenerNextClust( dword );
dword dwFnSetearNextClust(struct stuFsHandleFat * ,dword , dword );





uint16_t t16FnObtenerComienzoRootDir();
uint16_t t16FnObtenerTamanioRootDir();


void vFnAdaptarNombre (char *, char *);

void* pvFnCopiaArchivo( void *, const void *, dword );



int iFnBuscarArchivoFat (char *, stuFsDirectorioFAT *, stuFsHandleFat *);



void vFnListarRootDir(stuFsHandleFat *);
int iFnListarContenidoDir(stuFsDirectorioFAT *);



int iFnBuscarDirectorio (char *, stuFsHandleFat *);
int iFnExisteRaiz (const char *, stuFsHandleFat *);
int iFnBuscar(char *, int, stuFsHandleFat *);
# 380 "../include/fs/fat.h"
void vFnListarContenidoSubDir(char *);



int iFnBorrarFat(stuFsHandleFat *,char * );
int iFnBorrarArcDirectorio(char * );



void vFnBorrarArcFat(struct stuFsHandleFat * ,int);
# 398 "../include/fs/fat.h"
char * pTablaFat1;
char * pTablaFat2;
struct stuFsDirectorioFAT *stuFsDirectorioFATRootDir;
char stCadenaAux[512];




int iFnBuscarEntradaFATVacia();
int iFnBuscarEntradaFATLibre();
int iFnCargarFAT();
void vFnCargarRootDir();
void vFnRootDirToFloppy();
void vFnCopiaFatToFloppy();
unsigned int uiFnBuscarNextSector(unsigned int);
unsigned short usFnObtenerSectorFat(unsigned short);
void vFnSetearEnFat(unsigned short sector,unsigned short valor);
void vFnConvierteNombreToFAT(char *nombre, char *adaptado);

unsigned char* ucpFnCopiarMemoria( unsigned char *ucpDestino, unsigned char *ucpOrigen, unsigned int uiTamanio );
int iFnObtenerTamanioArchivo(char *);



typedef struct {
 char stPATH[255];
 int iCluster;
}stuPATH;

stuPATH stuPATHCD[1];





void TEST_BUSCA_FAT();
int TEST_WRITE_READ();
void imprimirTablaFAT( char *fat );
# 9 "fat.c" 2
# 1 "../include/kernel/libk/libk.h" 1
# 15 "../include/kernel/libk/libk.h"
dword dwFnCtod (char *stBuffer);
word wFnCtow (char *stBuffer);
byte byFnCtob (char *stBuffer);

int iFnDwtoBin (unsigned int uiNro, char *cCadenaDevualta);
int iFnDwtoOct (unsigned int uiNro, char *cCadenaDevualta);

void vFnItoa (int iNumero, char *stBuffer);
void vFnItoh (int iNumero, char *stBuffer);

void vFnWtoa (word wNumero, char *stBuffer);
void vFnWtoh (word wNumero, char *stBuffer);

void vFnBtoa (byte byNumero, char *stBuffer);
void vFnBtoh (byte byNumero, char *stBuffer);

int iFnHtoi (char *c);
int iFnCtoi (char *stBuffer);
int iFnXtoi (char *c);

extern void vFnFtoa(char *stBuffer, double fNumero, int iPrecision);
extern double fFnAtof(const char *stBuffer);
# 10 "fat.c" 2
# 1 "../include/kernel/libk/string.h" 1
# 9 "../include/kernel/libk/string.h"
inline unsigned char* ucpFnCopiarMemoria(unsigned char *ucpDestino,
      unsigned char *ucpOrigen,
      unsigned int uiTamanio);
inline unsigned char* ucpFnMemSetCero(unsigned char *ucpDirInicio,
                  unsigned int uiTamanio );

int iFnLongitudCadena (const char *cnstCadena);
int iFnCompararCadenas (const char *, const char *);
int iFnCompararCadenas2 (const char *, const char *);
int iFnCopiaCaracter (char *, const char *);
int iFnCopiaCadena (char *, const char *);

int iFnCopiaEntero (char *, const int);
int iFnCopiaFloat (char *, const float, const int);
int iFnCopiaWord (char *, const word);
int iFnCopiaByte (char *, const byte);
int iFnCopiaHexa (char *, const int);
int iFnCopiaWordHexa (char *, const word);
int iFnCopiaByteHexa (char *, const byte);
void vFnImprimirString (char *, const char *, ...);
int iFnLongitudCadena (const char *);

int iFnCopiaCadena2 (char *, const char *);
char * pstFnConcatenarCadena (char * , char * );
int iFnBuscarEnCadena (char * , char * ,int );
char * pstFnCadenaIzquierda (char * , int );
char * pstFnCadenaDerecha (char * , int );
int iFnEsNumero (char * stCadena);

void vFnStrLwr (char * stCadena);
void vFnStrUpr (char * stCadena);
# 11 "fat.c" 2
# 1 "../include/kernel/mem/mem_part_kernel.h" 1



void* ptrHeapBajoKernel;
long int liTamanioHeapBajoKernel;

void* ptrHeapAltoUsuario;
long int liTamanioHeapAltoUsuario;


long int liTamFijaMemBaja;
long int liTamFijaMemAlta;
long int liTamanioSolicitado;

int iModoMemoriaKernel;
char stTamanioMemFija[20];
int iTamanioMemFijaSeteado;
int iPosicionSetMemFija;
int iContinuar;
int iModoFijoUser;

void vFnInicializarHeapsKernel();
void vFnConfigurarParticiones();

void * pvFnReservarParticionUsuario(unsigned int);
void * pvFnReservarParticionKernel(unsigned int);
void * pvFnRedimensionarSegmento(void*, unsigned long);
void vFnLiberarParticion( void * );
unsigned int uiHeapKernelInicializado;
unsigned int uiKernelStack;
# 12 "fat.c" 2

# 1 "../include/kernel/syscall.h" 1







# 1 "../include/kernel/signal.h" 1
# 9 "../include/kernel/syscall.h" 2
# 1 "../include/kernel/semaforo.h" 1
# 20 "../include/kernel/semaforo.h"
typedef struct
{
 int inicializado;
 int valor;
 unsigned long int head;
 unsigned long int tail;

 unsigned long int procesosEnCola;

 unsigned long int cola[5];
 unsigned long int pshared;
}semaforo;





typedef struct
{
 int sem_id;
}sem_t;





typedef struct{
 int pshared;
 unsigned int value;
} sem_init_params;


void vFnEncolarProceso(semaforo *sem, unsigned long int uliId);


void vFnInicializaCola(unsigned long int *cola);


int iFnHayProcesoEnEspera(semaforo *sem);


unsigned long int uliFnDesencolarProceso(semaforo *sem);


void vFnInicializarSemaforos();
# 77 "../include/kernel/semaforo.h"
int iFnSemInit(sem_t *sem, int pshared, unsigned int value);
# 86 "../include/kernel/semaforo.h"
int iFnSemClose(sem_t *sem);
# 106 "../include/kernel/semaforo.h"
int iFnSemWait(sem_t *sem);
# 116 "../include/kernel/semaforo.h"
int iFnSemPost(sem_t *sem);

int validaExistenciaSemaforo(sem_t *sem);


int agregarSemaforoAlSistema(int pshared, unsigned int value);

void vFnVerSemaforos();
# 10 "../include/kernel/syscall.h" 2
# 1 "../include/kernel/shm.h" 1
# 18 "../include/kernel/shm.h"
typedef unsigned int size_t;
typedef int key_t;
typedef int bool;


typedef struct _stuMemoriasAtachadas_
{
 bool utilizada;
 int posicionEnShMem;
 int posicionEnAttach;
}stuMemoriasAtachadas;


typedef struct _attach_
{
 int pid;
 void * ptrShAddr;

}attach;


typedef struct _shMem_
{
 key_t key;
 unsigned long int tamanio;
 attach procAtt[5];
 bool declarada;
}shMem;

shMem memoriasCompartidas[5];




int iFnShmGet(key_t key, size_t size);


int iFnShmAt(int shmid, void * shmAddr);


int iFnShmDt(int shmid);

int iFnShmDtProc(int shmid, unsigned int uiPid);
int iFnShmDtAllProc(unsigned int uiPid);

unsigned long ulFnMaxDirShmProc(unsigned int uiPid);

void vFnInicializarShms();
void vFnVerShm();




void vFnCopiarVariablesCompartidas();



void vFnCopiarVariable(void * dest, void * src, size_t tamanio);
# 11 "../include/kernel/syscall.h" 2
# 1 "../include/kernel/tiempo.h" 1
# 53 "../include/kernel/tiempo.h"
typedef unsigned long int time_t;
typedef unsigned long int clock_t;





typedef struct{

        clock_t tms_utime;


        clock_t tms_stime;


        clock_t tms_cutime;


        clock_t tms_cstime;
} tms;





typedef struct{

        int tz_minuteswest;


        int tz_dsttime;
} timezone;





typedef struct{

        unsigned long int tv_sec;


        unsigned long int tv_usec;
} timeval;





typedef struct{

        timeval it_interval;


        timeval it_value;
} itimerval;





typedef struct{

        int modes;


 long offset;


 long freq;


 long maxerror;


 long esterror;


 int status;


 long constant;


 long precision;


 long tolerance;


 timeval time;


 long tick;
} timex;





typedef struct{

        long int tv_sec;


        long int tv_nsec;
} timespec;
# 12 "../include/kernel/syscall.h" 2
# 195 "../include/kernel/syscall.h"
enum __ptrace_request {
 PTRACE_TRACEME,
 PTRACE_PEEKTEXT,
 PTRACE_PEEKDATA,
 PTRACE_PEEKUSER,
 PTRACE_POKETEXT,
 PTRACE_POKEDATA,
 PTRACE_POKEUSER,
 PTRACE_GETREGS,
 PTRACE_GETFPREGS,
 PTRACE_SETREGS,
 PTRACE_SETFPREGS,
 PTRACE_CONT,
 PTRACE_KILL,
 PTRACE_ATTACH,
 PTRACE_DETACH
};


typedef struct {
 int iPid;
 void *pvAddr;
 void *pvData;
}__ptrace_param;



typedef struct _stuRegs_
{
  long ebx;
  long ecx;
  long edx;
  long esi;
  long edi;
  long ebp;
  long eax;
  int xds;
  int xes;
  long orig_eax;
  long eip;
  int xcs;
  long eflags;
  long esp;
  int xss;
} stuRegs;






long lFnSysExit( int status );
long lFnSysFork();
long lFnSysTest( long num );
long lFnSysRead( int, void *buf, size_t count );
long lFnSysWrite( int, const void *buf, size_t count );
long lFnSysWaitPid( int pid, int *status, int options );
long lFnSysExecve( const char *filename, char *argv[], char *envp[] );
long lFnSysTime( long *t );
long lFnSysGetPid();
long lFnSysKill( int pid, int sig );
long lFnSysGetPPid();
long lFnSysReboot( int flag );
long lFnSysSodiumCallgate(int iOpcion, int iPar1, int iPar2);
long lFnSysBrk(unsigned long);
long lFnSysSBrk(unsigned long);
long lFnSysSemInit( sem_t *sem, sem_init_params * params);
long lFnSysSemPost( sem_t *sem );
long lFnSysSemWait( sem_t *sem );
long lFnSysSemClose( sem_t *sem );
long lFnSysShmGet( key_t key, size_t size );
long lFnSysShmAt( int shmid, void * shmAddr );
long lFnSysShmDt( key_t key );

int iFnSysSumar(int a, int b, int * res);



long lFnSysNice( int );
long lFnSysGetpriority( int, int );
long lFnSysSetpriority( int, int, int );
long lFnSysClone(stuRegs *,int flags);


long lFnSysIdle();



long lFnSysSchedSetParam(int p);
long lFnSysSchedGetParam();
long lFnSysSchedSetScheduler(int p);
long lFnSysSchedGetScheduler();
long lFnSysSchedYield();
long lFnSysSchedGetPriorityMax();
long lFnSysSchedGetPriorityMin();
long lFnSysSchedRrGetInterval();





long lFnSysStime(time_t *newtime);
long lFnSysTimes(tms *ptmsbuffer);
long lFnSysGettimeofday(timeval *ptimervalTp, timezone *ptimezoneTzp);
long lFnSysSettimeofday(timeval *ptimevalTp, timezone *ptimezoneTzp);
long lFnSysGettimer(int iWhich, itimerval *pitimervalValue);
long lFnSysSettimer(int iWhich, itimerval const *pcnitimervalValue, itimerval *ptimervalOvalue);
long lFnSysAdjtimex(timex *ptimexBuffer);
long lFnSysNanosleep(timespec const *pcntimespecRequested_time, timespec *ptimespecRemaining);



long lFnSysPtrace( int request, void *pvDirParam );





unsigned long ulFnSysBrk(unsigned long brk);
# 14 "fat.c" 2
# 1 "../include/kernel/system.h" 1
# 22 "../include/kernel/system.h"
unsigned long int uliClockTick;





typedef struct
{
    unsigned int :16;
    unsigned int TSSSegmentSelector :16;
    unsigned int :8 ;
    unsigned int Type :5;
    unsigned int DPL :2;
    unsigned int P :1;
    unsigned int :16;
} __attribute__((packed)) t_TaskGate;





typedef struct
{
    unsigned int Offset1 :16;
    unsigned int SegmentSelector :16;
    unsigned int :5 ;
    unsigned int Type :8;
    unsigned int DPL :2;
    unsigned int P :1;
    unsigned int Offset2 :16;
} __attribute__((packed)) t_InterruptGate;




typedef struct
{
    unsigned int Offset1 :16;
    unsigned int SegmentSelector :16;
    unsigned int :5 ;
    unsigned int Type :8;
    unsigned int DPL :2;
    unsigned int P :1;
    unsigned int Offset2 :16;
} __attribute__((packed)) t_TrapGate;




typedef union
{
    t_TaskGate TaskGate;
    t_InterruptGate InterruptGate;
    t_TrapGate TrapGate;
}stuIDTDescriptor;




typedef struct
{
    stuIDTDescriptor IDTDescriptor[256];
} stuIDT;


typedef struct
{
    dword dwLimite :16;
    dword dwBase :32;
} t_IDTRegister;

stuIDT *pstuIDT;
unsigned char ucFnObtenerScanCode();
void vFnIniciarTeclado();
void vFnIniciarExcepciones();
void vFnIniciarIDT();
void vFnHandlerGenerico();
void vFnHandlerTimer();
void vFnPlanificador();
void vFnHandlerTeclado();
void* pvFnKernelStackAdmin();


void vFnHandlerDisquette();

long vFnHandlerSyscall( long eax,
   long ebx,
   long ecx,
   long edx );

void vFnLTR(unsigned int uiSelector);
unsigned int uiFnSTR(void);
# 15 "fat.c" 2
# 1 "../include/shell/teclado.h" 1
# 509 "../include/shell/teclado.h"
char stBufferShell[256];

char stBufferTeclado[10];






struct _stuKeyCode {
    unsigned char tipo;
    unsigned char ascii;
};

typedef struct _stuKeyCode stuKeyCode;




struct _stuDefinicionTeclado {
    char sCodigo [5];
    char sNombre [25];
    stuKeyCode stashMatrizNormal [128];
    stuKeyCode stashMatrizShifted [128];
    stuKeyCode stashMatrizAltGred [128];
} __attribute__((packed));

typedef struct _stuDefinicionTeclado stuDefinicionTeclado;


void vFnManejadorTecladoShell (unsigned char ucScanCode);
void vFnScanCodeAKeyCode( stuKeyCode*, unsigned char );
void vFnScanCodeExtAKeyCode( stuKeyCode*, unsigned char );
void vFnKeyCodeNumPad( stuKeyCode* );
int iFnTeclaEspecial ( stuKeyCode, unsigned char );
int iFnCombinacionTeclasEspecial( stuKeyCode );
void * pvFnAbrirArchivoKeymap (void);
int iFnCambiaTecladoI(unsigned int);
int iFnCambiaTecladoS(char *);
void vFnListarKeymaps();
char cFnGetChar();
char cFnPausa();

int iCantidadCaracteres;
int iSemaforoBufferTeclado;
int iLlenarIndice;
static int staiVaciarIndice;
# 16 "fat.c" 2
# 1 "../include/shell/shell.h" 1
# 13 "../include/shell/shell.h"
void vFnManejadorTecladoShell(unsigned char scanCode);

char cFnGetch();
char cFnPausa();
int iFnGetArg(int iPos, int iNumero, char* stResultado, int iAnchoMaximo);
int iFnXtoI (char *c);
int iFnHtoI (char *c);

void vFnAPM_info();
void vFnAPM_shutdown();

void vFnLoopReloj();
void vFnImprimirMenu ();
void vFnImprimirContexto();
void vFnMenuInstanciarInit();
void vFnMostrarListaParticiones();
void vFnBorrarUltimaPartFija();
void vFnAgregarPartFija(char*);
void vFnResetearListaPart();
int iFnShellActivo();


void vFnImprimirMenu ();
void vFnImprimirSeparadores ();




void vFnShell ();
void vFnMenuAyuda ();



void vFnMenuDump (int,int);
void vFnMenuWriteArch(int,int);
void vFnMenuOptKill(int);
void iFnTomaPrimerPara();
void iFnTomaNParametro(int,char *);
void vFnConvierteACadena(int, char *);



void vFnMenuKill (int);
void vFnMenuKillSeg (int);
void vFnMenuMem ();
void vFnMenuVer ();
void vFnMenuDesc (int,int);
void vFnMenuEjecutar(int);
void vFnMenuStack (int,int);
void vFnMenuGdt ();
void vFnMenuIdt ();
void vFnMenuCambiaTeclado (int);
void vFnMenuCls ();
void vFnMenuTSS (int);
void vFnMenuBitmap ();
void vFnMenuSegs ();
void vFnMenuPag (int);
void vFnMenuPs ();
void vFnMenuExec (int,int);
void vFnMenuExecSeg (int,int);
void vFnMenuLeerArch(int);
void vFnMenuCheck (int);
void vFnMenuSet (int);
void vFnSumaFpu (int);
void vFnMenuSumaFpu(int,int);
void vFnMenuVerSemaforos();
void vFnMenuVerShm();
void vFnMenuTestptrace(int);
void vFnMenuFd ();
void vFnMenuLs (int);
void vFnMenuCD(int);
void vFnMenuRm(int);

void vFnTermLog (unsigned char ucCaracter);

char *cpFnGetEnv(char *cpVariable);
void vFnGetAllEnv();
void vFnSetEnv(char *cpVariable, char *cpValor);
void vFnUnSetEnv(char *cpVariable);



typedef struct {
 char cpVariable[32 +1];
 char cpValor[32 +1];
 int iActiva;
}stuENV;




void vFnInicializarEnv();

stuENV pstuENV[10];


unsigned long ulPidProcesoForeground;
unsigned long uiAPM_ok;
unsigned long uiAPM_check_ax;
unsigned long uiAPM_check_bx;
unsigned long uiAPM_check_cx;

unsigned long uiAPM_32_cs;
unsigned long uiAPM_offset_entry_point;
unsigned long uiAPM_16_cs;
unsigned long uiAPM_ds;
# 17 "fat.c" 2
# 1 "../include/shell/sys_video.h" 1







# 1 "../include/video.h" 1
# 58 "../include/video.h"
typedef char* va_list;
# 100 "../include/video.h"
int iFnImprimirCadenas (int,const char*);




void vFnImprimirEntero (int,const int);




void vFnImprimirFloat (int,const double, const int);




void vFnImprimirHexa (int,const int);




void vFnImprimirWordHexa (int,const word);




void vFnImprimirByteHexa (int,const byte);





void vFnImprimirWin (int,const char*, ... );
void vFnImprimir (const char*, ... );
void vFnImprimirI (const char*, ... );

extern char cFnSysObtenerColor(int);
extern void vFnSysSetearColor(int,char);
extern void vFnSysSetearX(int,int);
extern void vFnSysSetearY(int,int);
extern void vFnClsWin(int);





void vFnImprimirContextSwitch(int color,int pid, char* nombre, int indiceGDT);
void vFnImprimirPrompt();
void vFnImprimirOk(int linea);
void vFnImprimirNOk(int linea);

void vFnImprimirVentana (int hVentana, const char *cnstCadena, ...);






int bTerminalActiva;

void vFnCambiarTerminal(void);
void vFnLog (const char *cnstCadena, ...);

void vFnLogScrollArriba();
void vFnLogScrollAbajo();

void vFnLogScrollMaximo();
void vFnLogScrollMinimo();
void vFnLogBorrar();
# 9 "../include/shell/sys_video.h" 2
# 21 "../include/shell/sys_video.h"
typedef struct _stuVentana_
{
  int iCursorX;
  int iCursorY;
  char cColor;
  int iPosicionX;
  int iPosicionY;
  int iAncho;
  int iAlto;
}stuVentana;

void vFnTabulador (int);
void vFnNuevaLinea (int);
void vFnBorrarCaracter (int);
void vFnScroll (int);
inline void vFnPonerCaracter (int, int);
char cFnObtenerColor (int);
void vFnSysSetearColor (int, char);
void vFnSysSetearX (int, int);
void vFnSysSetearY (int, int);
void vFnCambiarVisibilidadVentanaProceso ();
void vFnClsWin (int);
# 18 "fat.c" 2
# 1 "../include/kernel/drivers/floppy.h" 1







# 1 "../include/kernel/drivers/dma.h" 1
# 89 "../include/kernel/drivers/dma.h"
void inicDMA();
void setCanalDMA(u8 Canal, u32 Direccion, u8 Modo, u16 Cuenta);
void setMascaraDMA(u8 Mascara);
void setDirDMA(u8 Canal, u32 Direccion);
void setContDMA(u8 Canal, u16 Cuenta);
void setModoDMA(u8 Modo);
void habilitarCanal(u8 Canal);
void inhibirCanal(u8 Canal);
u8 peticionDMA(u8 Canal);
u8 TCDMA(u8 Canal);
# 9 "../include/kernel/drivers/floppy.h" 2
# 19 "../include/kernel/drivers/floppy.h"
typedef struct {u8 RST0; u8 Valido;} ST0_t;
typedef struct {u8 RST1; u8 Valido;} ST1_t;
typedef struct {u8 RST2; u8 Valido;} ST2_t;




typedef struct
{
 u8 Cilindro;
 u8 Cabeza;
 u8 Sector;
}
CHS;




typedef enum
{
 Termin_Normal, Term_Anormal, Com_No_Finalizado, Com_Invalido
}Estado;


void* pvBufferDmaFloppy;
byte byBufferDmaNoAlineadoFloppy[512*2];
void* alinearBufferFloppyDMA(void* Buffer, unsigned long ulTamanioTotal);

u8 leerSector (byte* Buffer, u16 NBloque);
u8 escribirSector (byte* Buffer, u16 NBloque);
u8 operExitosa ();
void prenderMotor ();
void apagarMotor ();
u8 envComRecalibrado ();
u8 envComDesplCabeza (u8 Cilindro, u8 Cabeza);
u8 envComLectura (u8 Cilindro, u8 Cabeza, u8 Sector);
u8 envComEscritura (u8 Cilindro, u8 Cabeza, u8 Sector);
void enviarDatosOper (u8 Cilindro, u8 Cabeza, u8 Sector);
u8 leerEstadoFDC ();
void leerST0 ();
u8 leerST3 ();
u8 vFnImprimirST0 ();
void vFnImprimirST1 ();
void vFnImprimirST2 ();
void vFnImprimirST3 ();
void vFnImprimirEstadoFDC ();
u8 listoPES ();
u8 esperandoByteProc ();
u8 bytePProcesador ();
u8 FDCOcupado ();
u8 unidadOcupada ();
void obtResOper ();
void invalidarEstados ();
CHS LBAaCHS (u16 NBloque);

void ISRDisketeraC();
# 19 "fat.c" 2






void vFnInicializarPath()
{
 int iN ;
 for (iN = 0 ; iN < 254 ; iN++)
 {
  stuPATHCD[0].stPATH[iN]= ' ';
 }
 iFnCopiaCadena(stuPATHCD[0].stPATH,"/");
}







void vFnAdaptarNombre (char *puNombreFat, char *puNombreAdaptado)
{
 int iX=0,iZ;
 iFnCopiaCadena(puNombreAdaptado,"            ");
 for( iZ=0 ; iZ<11 ; iZ++)
 {
  if ( (iZ==8) && (puNombreFat[8]!=' ') )
  {
   puNombreAdaptado[iX]='.';
   iX++;
  }
  puNombreAdaptado[iX] = puNombreFat[iZ];
  if (puNombreFat[iZ] != ' ')
  iX++;
 }
 puNombreAdaptado[iX]='\0';
}







uint16_t t16FnObtenerTamanioRootDir()
{

 return ((pstuFsFatHandleHandle->header->root_entries * sizeof(stuFsDirectorioFAT)) / 512);
}






uint16_t t16FnObtenerComienzoRootDir()
{

 return ( 1 + pstuFsFatHandleHandle->header->hidden_sectors + (pstuFsFatHandleHandle->header->fats * pstuFsFatHandleHandle->header->sectors_per_fat));
}
# 90 "fat.c"
int iFnBuscarArchivoFat (char *pcNombre, stuFsDirectorioFAT *pstFsFatDirentDatosArchivo , stuFsHandleFat *pstuFsFatHandleHandle)
{

 char stNombreAux[29];
 char stNombreArchivos[29];
 char stNombreMay[29];

 int iJ ;
 int iDirLen;

 uint8_t uRootDirFlag=1;

 dword dwDirSector, dwTamanioDir;


 iFnCopiaCadena(stNombreMay, pcNombre) ;

 vFnStrUpr(stNombreMay);



 dwDirSector = t16FnObtenerComienzoRootDir();
 dwTamanioDir = t16FnObtenerTamanioRootDir();


 stuFsDirectorioFAT *pstuFsFatDirentAuxFat;

 do
 {

  iFnBuscarArchivo_break:

   if ((iDirLen=iFnLongitudCadena(stNombreMay)) > 0)
   {

    iFnCopiaCadena(stNombreAux,pstFnCadenaIzquierda(pcNombre,iDirLen));
    pcNombre = pcNombre + iDirLen + 1;
   }
   else
   {
    if(iFnCopiaCadena(stNombreAux, stNombreMay) <= 0)
    { vFnImprimir("NO SE COPIO NADA!\n");
     return -1;
    }
   }


  do
  {

   leerSector( byBuffer ,dwDirSector);

   pstuFsFatDirentAuxFat = (stuFsDirectorioFAT *) byBuffer;

   for( iJ=0 ; iJ < (512 / sizeof(stuFsDirectorioFAT)) ; iJ++)
   {

    if( (pstuFsFatDirentAuxFat->filename[0]!=' ') &&(pstuFsFatDirentAuxFat->filename[0]!=0) && (pstuFsFatDirentAuxFat->filename[0]!=0xE5) && !(pstuFsFatDirentAuxFat->attributes & 0x0D) )
    {
     vFnAdaptarNombre( pstuFsFatDirentAuxFat->filename , stNombreArchivos);
     if ( iFnCompararCadenas( stNombreArchivos, stNombreAux)==1 )
     {
      if (iDirLen < 0)
      {
       ucpFnCopiarMemoria( (unsigned char*) pstFsFatDirentDatosArchivo, (unsigned char*) pstuFsFatDirentAuxFat, sizeof(stuFsDirectorioFAT));
       vFnImprimir("\n**********ARCHIVO!!!!!************************\n");

       return 1;
      }
      dwDirSector = pstuFsFatDirentAuxFat->starting_cluster + 31;


      dwTamanioDir = 0xffff;
      uRootDirFlag=0;

      goto iFnBuscarArchivo_break;
     }
    }

    pstuFsFatDirentAuxFat++;
   }
   if (uRootDirFlag==1)
   {
    dwDirSector++;

    if (dwDirSector > (t16FnObtenerComienzoRootDir() + t16FnObtenerTamanioRootDir() ))
    return 0;
   }
   else
   {

    if ((dwDirSector = pstuFsFatHandleHandle->get_next_cluster( pstuFsFatHandleHandle->fat1, dwDirSector ))==0xFFF)
    return 0;
   }
  } while (dwDirSector != 0xFFF );



 }
 while ( iDirLen > 0 );


 return 0;
}







int iFnListarContenidoDir(stuFsDirectorioFAT *pstuFsFatDirentDirEntr)
{
 static int iN=0;
  if (iN==0)
  vFnImprimir("\n stNombre \tStarting Cluster \tTamanio del Archivo \t fecha");
    if( (pstuFsFatDirentDirEntr->filename[0]!=' ') &&(pstuFsFatDirentDirEntr->filename[0]!=0) && (pstuFsFatDirentDirEntr->filename[0]!=0xE5) && !(pstuFsFatDirentDirEntr->attributes & 0x0D) )
 {
  char stNombre[12];

  vFnAdaptarNombre(pstuFsFatDirentDirEntr->filename , stNombre);

   vFnImprimir("\n %s\t\t%d\t\t%d\t\t%d/%d/%d %d:%d:%d",
   stNombre ,
   pstuFsFatDirentDirEntr->starting_cluster,
   pstuFsFatDirentDirEntr->filesize ,
      ((((pstuFsFatDirentDirEntr->create_date) & 0xfe00) >> 9) + 1980),
        (((pstuFsFatDirentDirEntr->create_date) & 0x01e0) >> 5),
        (((pstuFsFatDirentDirEntr->create_date) & 0x001f) >> 0),
        (((pstuFsFatDirentDirEntr->create_time) & 0xf800) >> 11),
        (((pstuFsFatDirentDirEntr->create_time) & 0x07e0) >> 5),
        ((((pstuFsFatDirentDirEntr->create_time) & 0x001f) >> 0) * 2)
       );
# 231 "fat.c"
    iN++;
 }
 return 0;
}






void vFnListarRootDir(stuFsHandleFat *pstuFsFatHandleHandle)
{

 int iSectorOriRoot= 19;

 int iX, iW,iCantSector;


 stuFsDirectorioFAT *pstuFsFatDirentDatos;


 iCantSector = 14;


 for ( iX=iSectorOriRoot ; iX < (iSectorOriRoot + iCantSector);iX++)
 {

  if(leerSector(byBuffer ,iX)!=1)
  {
    vFnImprimir("Error al leer sector del diskette");
    return;
  }


  pstuFsFatDirentDatos = (stuFsDirectorioFAT*)byBuffer;

  for( iW=0 ; iW < 16 ; iW++)
  {


   if ( (pstuFsFatDirentDatos->filename[0]!=0) && !(pstuFsFatDirentDatos->attributes & 0x0D ) && !(pstuFsFatDirentDatos->attributes & 0x02) )
   {

    iFnListarContenidoDir( pstuFsFatDirentDatos );
   }
   pstuFsFatDirentDatos++;
  }
 }
 return;
}







int iFnExisteRaiz (const char *pstNombre , struct stuFsHandleFat *pstuFsFatHandleHandle)
{

 char stNombreAux[29];
 char stNombreArchivos[29];
 char stNombreMay[29];
 int iJ ;

 dword dwDirSector, dwTamanioDir;

 if(pstNombre[0] =='/')
  iFnCopiaCadena(stNombreMay, pstFnCadenaDerecha(pstNombre,iFnLongitudCadena(pstNombre)-1)) ;
 else
 iFnCopiaCadena(stNombreMay, pstNombre) ;

 vFnStrUpr(stNombreMay);



 dwDirSector = 19;
 dwTamanioDir = 14;


 stuFsDirectorioFAT *pstuFsFatDirentAuxFat;

  if(iFnCopiaCadena(stNombreAux, stNombreMay) <= 0)
  { vFnImprimir("NO SE COPIO NADA!\n");
  return -1;
  }

 do
  {

   leerSector(byBuffer ,dwDirSector);

   pstuFsFatDirentAuxFat = (stuFsDirectorioFAT *) byBuffer;

   for( iJ=0 ; iJ <16 ; iJ++)
   {

    if( (pstuFsFatDirentAuxFat->filename[0]!=' ') &&(pstuFsFatDirentAuxFat->filename[0]!=0) && (pstuFsFatDirentAuxFat->filename[0]!=0xE5) && !(pstuFsFatDirentAuxFat->attributes & 0x02) && !(pstuFsFatDirentAuxFat->attributes & 0x0D) && !(pstuFsFatDirentAuxFat->attributes & 0x20))
    {
     vFnAdaptarNombre( pstuFsFatDirentAuxFat->filename , stNombreArchivos);

     if ( iFnCompararCadenas( stNombreArchivos, stNombreAux)==1 )
     {
       return pstuFsFatDirentAuxFat->starting_cluster;
     }
    }

    pstuFsFatDirentAuxFat++;
   }

   dwDirSector++;

   if (dwDirSector > (33))
   {
    dwDirSector = 0xFFF;
       }

  } while (dwDirSector != 0xFFF );


 return -1;
}
# 361 "fat.c"
int iFnBuscar(char *pstNombreAux, int iClusterIni, stuFsHandleFat *pstuFsFatHandleHandle)
{

 char stNombreArchivos[29];
 char stNombreMay[29];
 int iJ;

 dword dwDirSector;


 if(iFnCopiaCadena(stNombreMay,pstNombreAux) <= 0)
 {
  vFnImprimir("NO SE COPIO NADA!\n");
  return -1;
 }

 vFnStrUpr(stNombreMay);


 dwDirSector = iClusterIni + 31;


 stuFsDirectorioFAT *pstuFsFatDirentAuxFat;

 do
 {

  if (leerSector(byBuffer ,dwDirSector) ==1)
  {
   vFnImprimir("LEYO\n");
  }

  pstuFsFatDirentAuxFat = (stuFsDirectorioFAT *) byBuffer;


  for( iJ=0 ; iJ < (16) ; iJ++)
  {

   if( (pstuFsFatDirentAuxFat->filename[0]!=' ') &&(pstuFsFatDirentAuxFat->filename[0]!=0) &&
    (pstuFsFatDirentAuxFat->filename[0]!=0xE5) && !(pstuFsFatDirentAuxFat->attributes & 0x0D) &&
    !(pstuFsFatDirentAuxFat->attributes & 0x20))
   {
    vFnAdaptarNombre( pstuFsFatDirentAuxFat->filename , stNombreArchivos);
    if ( iFnCompararCadenas( stNombreArchivos, stNombreMay)==1 )
    {
     vFnImprimir("EL dwDirSector ES %d\n", pstuFsFatDirentAuxFat->starting_cluster);
     return pstuFsFatDirentAuxFat->starting_cluster;
    }
   }

   pstuFsFatDirentAuxFat++;
  }

  if ((dwDirSector = pstuFsFatHandleHandle->get_next_cluster( pstuFsFatHandleHandle->fat1, dwDirSector ))==53)
  {
   vFnImprimir("el ultimo sector es\n");
   dwDirSector= 53;
   return 0;
  }
 } while (dwDirSector < 53);

 vFnImprimir("no lo encontro\n");

 return 0;
}
# 434 "fat.c"
int iFnBuscarDirectorio (char *pcNombre, struct stuFsHandleFat * pstuFsFatHandleHandle )
{
 char stNombreAux[255];
 int iDirLen;
 int iClusterIni= 0;



  if ( (iDirLen=iFnBuscarEnCadena(pcNombre,"/",0))>0 )
  {
         iFnCopiaCadena(stNombreAux,pstFnCadenaIzquierda(pcNombre,iDirLen-1));
   iClusterIni=iFnExisteRaiz(stNombreAux,pstuFsFatHandleHandle);

   if( iClusterIni ==-1)
    iClusterIni=0;
   }
 return iClusterIni;

}







void vFnListarContenidoSubDir(char *stRuta)
{

 int iJ, iClusterIni;
 dword dwDirSector;
 stuFsDirectorioFAT *pstuFsFatDirentAuxFat;

   if(iFnCompararCadenas(stRuta, "") ==1)
 {
   iFnCopiaCadena(stRuta, stuPATHCD[0].stPATH);
 }

  if(iFnCompararCadenas(stRuta, "/") ==1)
  {
   vFnImprimir("listando root dir\n");
   vFnListarRootDir( pstuFsFatHandleHandle);
   return;
  }

  if ( stRuta[0] =='/' || stRuta[0] == ' ' )
  {
   vFnImprimir("Argumento invalido\n");
   return;
  }
  if(stuPATHCD[0].stPATH[0]=='-' || stuPATHCD[0].stPATH[0]== "" || stuPATHCD[0].stPATH[0]== " ")
  {vFnImprimir("Argumento invalido\n");return;}

  iClusterIni= iFnBuscarDirectorio(stRuta, pstuFsFatHandleHandle);
  if (iClusterIni==0)
  {
   vFnImprimir("Ruta no valida\n");
   return;
  }

  dwDirSector = iClusterIni + 31;

  do
  {

  if(leerSector(byBuffer ,dwDirSector)!=1)
  {
    vFnImprimir("Error al leer sector del diskette");
    return;
  }
   pstuFsFatDirentAuxFat = (stuFsDirectorioFAT *) byBuffer;


   for( iJ=0 ; iJ < (16) ; iJ++)
   {

    if((pstuFsFatDirentAuxFat->filename[0]!=' ') && (pstuFsFatDirentAuxFat->filename[0]!=0) &&
     iFnCompararCadenas(pstuFsFatDirentAuxFat->filename,"E5")!=1 && !(pstuFsFatDirentAuxFat->attributes & 0x0D) &&
     ( (pstuFsFatDirentAuxFat->attributes & 0x20) || (pstuFsFatDirentAuxFat->attributes & 0x10)) )
    {
     iFnListarContenidoDir( pstuFsFatDirentAuxFat );
    }
    pstuFsFatDirentAuxFat++;
   }

   dwDirSector = dwFnObtenerNextClust(dwDirSector);

  } while (dwDirSector < 0xFFF );


}






dword dwFnObtenerNextClust( dword dwDirSector )
{
 uint16_t uAux;
 uAux = ( dwDirSector + dwDirSector / 2 );

 if( dwDirSector % 2 )
 {
  dwDirSector= (uAux & 0xfff0) * 16;
 }

 else
 {
  dwDirSector= (uAux & 0x0fff);

 }
        return dwDirSector;
}
# 557 "fat.c"
dword dwFnSetearNextClust(struct stuFsHandleFat * pstuFsFatHandleHandle, dword dwCluster, dword dwNext )
{
 int iN;




 int iSectores = 9;

 uint16_t *uAux = (uint16_t*) ( (pstuFsFatHandleHandle->fat1) + (dwCluster) * 3/2 ) ;

 if( dwCluster % 2 )
 {
  *uAux = (dwNext << 4) | (*uAux & 0xf);
 }
 else
 {
  *uAux = dwNext | (*uAux & 0xf000);
 }


 for ( iN=1 ; iN<=iSectores ; iN++)
 {
  if( escribirSector(pstuFsFatHandleHandle->fat1 + (512 * iN),iN ) != 1)
   vFnImprimir("No se pudo escribir el sector %d de la iFnObtenerFat12() \n", iN);
 }
 return *uAux;
}
# 593 "fat.c"
int iFnBorrarFat(stuFsHandleFat * pstuFsFatHandleHandle,char * pcNombre)
{


 dword dwCluster;


 dwCluster = iFnBorrarArcDirectorio(pcNombre);

 return 0;
}







void vFnBorrarArcFat (struct stuFsHandleFat * pstuFsFatHandleHandle,int iClusterIni)
{

 dword dwProximoCluster;

 while (iClusterIni < 0xFFF )
 {
  vFnImprimir("iClusterIni %d \n ",iClusterIni);
  dwProximoCluster= dwFnObtenerNextClust( iClusterIni);
  dwFnSetearNextClust(pstuFsFatHandleHandle,iClusterIni, 0 );
  iClusterIni = dwProximoCluster;
 }
}







int iFnBorrarArcDirectorio(char * pcNombre)
{
 char stNombreMay[29];
 char stNombreArchivos[29];


 int iSectorOriRoot= 19;
 int iDel = 229;

 int iX, iW,iCantSector;
 stuFsDirectorioFAT *pstuFsFatDirentDatos;



 iCantSector = 14;
 iFnCopiaCadena(stNombreMay, pcNombre);

 vFnStrUpr(stNombreMay);

 for ( iX=iSectorOriRoot ; iX < (iSectorOriRoot + iCantSector);iX++)
 {

  leerSector(byBuffer ,iX);

  pstuFsFatDirentDatos = (stuFsDirectorioFAT*)byBuffer;

  for( iW=0 ; iW < 16 ; iW++)
  {



   if ( (pstuFsFatDirentDatos->filename[0]!=0) &&
    iFnCompararCadenas(pstuFsFatDirentDatos->filename,"E5")!=1 &&
    !(pstuFsFatDirentDatos->attributes & 0x0D )&&
    !(pstuFsFatDirentDatos->attributes & 0x02) )
   {
     vFnAdaptarNombre( pstuFsFatDirentDatos->filename , stNombreArchivos);
     if ( iFnCompararCadenas( stNombreArchivos, stNombreMay)==1 )
     {


       pstuFsFatDirentDatos->filename[0]= iDel;
       escribirSector(byBuffer, iX);
       return pstuFsFatDirentDatos->starting_cluster;
     }
   }
   pstuFsFatDirentDatos++;
  }
 }
 return 0;
}







uint8_t * t8FnObtenerDirRoot()
{

 uint8_t uCantSectoresRoot = pstuFsFatHandleHandle->header->root_entries * sizeof(stuFsDirectorioFAT) / 512;

 uint8_t uComienzoRoot = pstuFsFatHandleHandle->header->sectors_per_fat * pstuFsFatHandleHandle->header->fats + 1;

 uint8_t uCantBytesRoot = uCantSectoresRoot * 512;

 uint8_t* uBufferRoot = (uint8_t*)pvFnReservarParticionKernel(uCantBytesRoot);

     if (uBufferRoot == 0)
     {
  return 0;
 }


 leerSector(uBufferRoot ,uComienzoRoot);


     return uBufferRoot;
}






int iFnObtenerEncabezado()
{
 int iN;
 byte * byAuxByte;
 word * wAuxWord;
 dword * dwAuxDword;
 stuSectorBooteo *pstuBootSectorAux;
 if(leerSector(byBuffer, 0) != 1)
 { vFnImprimir("No se pudo leer sector\n");
  return -1;
 }

  pstuBootSectorAux= (stuSectorBooteo *) byBuffer;


 pstuFsFatHandleHandle->header = (struct stuFsEncabezadoFAT*) pvFnReservarParticionKernel(512);




 for (iN = 0 ; iN < 3 ; iN++)
 {
  byAuxByte = (byte*)(int)byBuffer + iN;
  pstuFsFatHandleHandle->header->ignored[iN] = *byAuxByte ;
 }

 for (iN = 3;iN < 11; iN++)
 {
  byAuxByte = (byte*)(int)byBuffer + iN;
  pstuFsFatHandleHandle->header->oem_id[iN]= *byAuxByte;
 }

  wAuxWord = (word*)(int)byBuffer + 11;
 pstuFsFatHandleHandle->header->bytes_per_sector = *wAuxWord;

 byAuxByte = (byte*)(int)byBuffer + 13;
 pstuFsFatHandleHandle->header->sectors_per_cluster = *byAuxByte;

 wAuxWord = (word*)(int)byBuffer + 14;
 pstuFsFatHandleHandle->header->reserved_sectors = *wAuxWord;

 byAuxByte = (byte*)(int)byBuffer + 16;
 pstuFsFatHandleHandle->header->fats = *byAuxByte;

 wAuxWord = (word*)(int)byBuffer + 17;
 pstuFsFatHandleHandle->header->root_entries = *wAuxWord;

 wAuxWord = (word*)(int)byBuffer + 19;
 pstuFsFatHandleHandle->header->small_sectors = *wAuxWord;

 byAuxByte = (byte*)(int)byBuffer + 21;
 pstuFsFatHandleHandle->header->media_descriptor = *byAuxByte;

 wAuxWord = (word*)(int)byBuffer + 22;
 pstuFsFatHandleHandle->header->sectors_per_fat = *wAuxWord;

 wAuxWord = (word*)(int)byBuffer + 24;
 pstuFsFatHandleHandle->header->sectors_per_track = *wAuxWord;

 wAuxWord = (word*)(int)byBuffer + 26;
 pstuFsFatHandleHandle->header->heads = *wAuxWord;

 dwAuxDword = (dword*)(int)byBuffer + 28;
 pstuFsFatHandleHandle->header->hidden_sectors = *dwAuxDword;

 dwAuxDword = (dword*)(int)byBuffer + 32;
 pstuFsFatHandleHandle->header->large_sectors = *dwAuxDword;

 byAuxByte = (byte*)(int)byBuffer + 36;
 pstuFsFatHandleHandle->header->physical_drive_number = *byAuxByte;

 byAuxByte = (byte*)(int)byBuffer + 37;
 pstuFsFatHandleHandle->header->current_head = *byAuxByte;

 byAuxByte = (byte*)(int)byBuffer + 38;
 pstuFsFatHandleHandle->header->signature = *byAuxByte;

 dwAuxDword = (dword*)(int)byBuffer + 39;
 pstuFsFatHandleHandle->header->volume_id = *dwAuxDword;
 for (iN = 43;iN < 55; iN++)
 {
  byAuxByte = (byte*)(int)byBuffer + iN;
  pstuFsFatHandleHandle->header->volume_label[iN]=*byAuxByte;
 }
 for (iN = 55;iN < 63; iN++)
 {
  byAuxByte = (byte*)(int)byBuffer + iN;
  pstuFsFatHandleHandle->header->fs_type[iN]=*byAuxByte;
 }
 if( !pstuFsFatHandleHandle->header )
 {
  return -1;
 }
 return 0;
}





void vFnMostrarEncabezado()
{
 int iN ;
 vFnImprimir("ignored: ") ;
 for (iN = 0 ; iN < 3 ; iN++)
  vFnImprimir("0x%iX",pstuFsFatHandleHandle->header->ignored[iN]) ;

 vFnImprimir("\noem_id: %s\n",pstuFsFatHandleHandle->header->oem_id) ;
 vFnImprimir("bytes_per_sector: %d\n",pstuFsFatHandleHandle->header->bytes_per_sector) ;
 vFnImprimir("sectors_per_cluster: %d\n",pstuFsFatHandleHandle->header->sectors_per_cluster) ;
 vFnImprimir("reserved_sectors: %d\n",pstuFsFatHandleHandle->header->reserved_sectors) ;
 vFnImprimir("fats: %d\n",pstuFsFatHandleHandle->header->fats) ;
 vFnImprimir("root_entries: %d\n",pstuFsFatHandleHandle->header->root_entries) ;
 vFnImprimir("small_sectors: %d\n",pstuFsFatHandleHandle->header->small_sectors );
 vFnImprimir("media_descriptor: %d\n",pstuFsFatHandleHandle->header->media_descriptor) ;
 vFnImprimir("sectors_per_fat: %d\n",pstuFsFatHandleHandle->header->sectors_per_fat) ;
 vFnImprimir("sectors_per_track: %d\n",pstuFsFatHandleHandle->header->sectors_per_track) ;
 vFnImprimir("heads: %d\n",pstuFsFatHandleHandle->header->heads) ;
 vFnImprimir("hidden_sectors: %d\n",pstuFsFatHandleHandle->header->hidden_sectors) ;
 vFnImprimir("large_sectors: %d\n",pstuFsFatHandleHandle->header->large_sectors) ;
 vFnImprimir("physical_drive_number: %d\n",pstuFsFatHandleHandle->header->physical_drive_number );
 vFnImprimir("current_head: %d\n",pstuFsFatHandleHandle->header->current_head) ;
 vFnImprimir("signature: %d\n",pstuFsFatHandleHandle->header->signature);
 vFnImprimir("volume_id: %d\n",pstuFsFatHandleHandle->header->volume_id) ;

 return;
}






int iFnObtenerFat12()
{
 int iN;

 int iFatBytes = pstuFsFatHandleHandle->header->sectors_per_fat * 512;

 int iSectores = iFatBytes /512;

  pstuFsFatHandleHandle->fat1 = (uint8_t *)pvFnReservarParticionUsuario(iFatBytes);


 for ( iN=0 ; iN<iSectores ; iN++)
 {
  if( leerSector(pstuFsFatHandleHandle->fat1 + 512 * iN,iN ) != 1)
  {
   vFnImprimir("No se pudo leer sector %d de la iFnObtenerFat12() \n", iN);
  }
 }
 for ( iN=0 ; iN<iSectores ; iN++)
 {
  if( leerSector(pstuFsFatHandleHandle->fat3 + 512 * iN,iN ) != 1)
  {
   vFnImprimir("No se pudo leer sector %d de la iFnObtenerFat12() \n", iN);
  }
 }
 if( !pstuFsFatHandleHandle->fat1 )
  return -1;
 return 0;
}






int iFnObtenerCopiaFat12(){
 int iN;

 uint8_t fatBytes = pstuFsFatHandleHandle->header->sectors_per_fat * 512;

 int iSectores = fatBytes /512;

 pstuFsFatHandleHandle->fat2 = (uint8_t*)pvFnReservarParticionUsuario(fatBytes);

 for ( iN=0 ; iN<iSectores ;iN++)
 {
  if( leerSector(pstuFsFatHandleHandle->fat2 + (512 * iN ),iN +(pstuFsFatHandleHandle->header->reserved_sectors + pstuFsFatHandleHandle->header->sectors_per_fat)) != 1)
  {
   vFnImprimir("No se pudo leer sector %d de la iFnObtenerCopiaFat12() \n", iN);
  }
 }

 if( !pstuFsFatHandleHandle->fat2 )
  return -1;

 return 0;
}







int iFnIniciarFileSystFloppy()
{
 if(iFnObtenerEncabezado()!=0)
  return -1;

 if(iFnObtenerFat12()!=0)
  return -1;

 if(iFnObtenerCopiaFat12()!=0)
  return -1;

 iFnCargarFAT();

   return 0;
}






int iFnIniciarFatDrv ()
 {




 pstuFsFatHandleHandle->header = 0;
 pstuFsFatHandleHandle->fat1 = 0;
 pstuFsFatHandleHandle->fat2 = 0;

 pstuFsFatHandleHandle->get_constant = 0;
 pstuFsFatHandleHandle->get_next_cluster = 0;
 pstuFsFatHandleHandle->set_next_cluster = 0;

 if(iFnIniciarFileSystFloppy() != 0)
 {
  vFnImprimir( "\nNO SE PUDO INICIALIZAR EL FLOPPY\n" );
  return -1;
 }

  if( !memcmp( pstuFsFatHandleHandle->fat1, "\xf8\xff\xff", 3 ) )
 {
  pstuFsFatHandleHandle->get_constant = t16FnFat12DrvGetConst;
  pstuFsFatHandleHandle->get_next_cluster = t16FnFat12DrvGetNextClust;
  pstuFsFatHandleHandle->set_next_cluster = t16FnFat12DrvSetNextClust;
 }
 else if( !memcmp( pstuFsFatHandleHandle->fat1, "\xf0\xff\xff", 3 ) )
 {
  pstuFsFatHandleHandle->get_constant = t16FnFat12DrvGetConst;
  pstuFsFatHandleHandle->get_next_cluster = t16FnFat12DrvGetNextClust;
  pstuFsFatHandleHandle->set_next_cluster = t16FnFat12DrvSetNextClust;
 }
 else
 {
  return -2;
 }
 return 0;
 }






void vFnIniciarCacheFloppy ()
{
 int iN;

 for(iN=0 ; iN< 511 ; iN++)
 {
  byBufferRead[iN]=0;
     }

   return;
}






void vFnLeerArchivo (dword dwSector)
{
 int iN;

 if(leerSector(byBufferRead, dwSector+31) != 1)
 {
  vFnImprimir("No se pudo leer sector %d\n", dwSector);
  return;
 }

 for ( iN=0; iN<512 ; iN++ )
  vFnImprimir("%c", byBufferRead[iN]);

}







uint16_t t16FnFat12DrvGetConst( uint16_t uConstante ){
 switch( uConstante )
 {
  case( 1 ): return 0x000;
  case( 2 ): return 0x001;
  case( 3 ): return 0x002;
  case( 4 ): return 0xFF7;
  case( 5 ): return 0xFF8;
  default: return 0;
 }
}






void vFnDispLeerArchivo(char *pcNombre)
{
 stuFsDirectorioFAT stuFsFatDirentDatosArchivo;
 stuFsDirectorioFAT *pstuFsFatDirentDatosArchivo=&stuFsFatDirentDatosArchivo;
 uint32_t uCluster;
 uint32_t uTamanioArchivo;
 int iCantSectores, iSectoresLeidos=0;

 iFnObtenerEncabezado();
 iFnCargarFAT();
 vFnCargarRootDir();
 if(iFnBuscarArchivoFat (pcNombre, pstuFsFatDirentDatosArchivo, pstuFsFatHandleHandle) == 1)
 {
  vFnImprimir("Nombre: %s\n", pstuFsFatDirentDatosArchivo->filename) ;
  vFnImprimir("Cluster Inicial: %d\n", pstuFsFatDirentDatosArchivo->starting_cluster);
  uCluster = pstuFsFatDirentDatosArchivo->starting_cluster;
  uTamanioArchivo = pstuFsFatDirentDatosArchivo->filesize;

  iCantSectores = (uTamanioArchivo/512);
  if((uTamanioArchivo % 512) !=0)
  {
   iCantSectores = iCantSectores +1;
  }
  vFnImprimir("Cantidad de Sectores a leer: %d\n", iCantSectores);
  vFnImprimir("\nCONTENIDO DEL ARCHIVO:\n");
  while((iSectoresLeidos < iCantSectores))
  {
   vFnLeerArchivo(uCluster);
   uCluster = uiFnBuscarNextSector(uCluster);
   iSectoresLeidos++;
  }
 }
 else
 {
  vFnImprimir("\nArchivo %s no encontrado\n", pcNombre);
  return;
 }

 return;
}
# 1083 "fat.c"
int memcmp(const void *pconvS1, const void *pconvS2, dword dwN)
{
 byte *bySS2 = (byte *) pconvS2;
      byte *byS11 = (byte *) pconvS1;

      while (dwN--)
 {
          if (*byS11 != *bySS2 )
               return (int) (byS11-bySS2);
          bySS2++;byS11++;
      }

      return 0;
}
# 1105 "fat.c"
uint16_t t16FnFat12DrvGetNextClust( uint8_t *uFat, uint16_t uCluster )
{
 uint16_t uAux = ( uCluster + uCluster / 2 );
 if( uCluster % 2 )
 {
  return (uAux & 0xfff0) * 16;
 }
 else
 {
  return (uAux & 0x0fff);
 }
}
# 1126 "fat.c"
uint16_t t16FnFat12DrvSetNextClust( uint8_t *uFat,uint16_t uCluster, uint16_t dwNext )
{
 uint16_t *uAux = (uint16_t*) t8FnFatDrvGetClustAddr( uFat, uCluster );

 if( uCluster % 2 ){
  *uAux = (dwNext << 4) | (*uAux & 0xf);
 }
 else
 {
  *uAux = dwNext | (*uAux & 0xf000);
 }

 return *uAux;
}
# 1148 "fat.c"
uint8_t* t8FnFatDrvGetClustAddr( uint8_t *uFat, uint16_t uCluster )
{
 return( (uFat) + (uCluster) * 3/2 );
}
# 1160 "fat.c"
int iFnDispEscribirArchivo (char *pcNombre, char *pcContArch){

    int iIndiceFat, iIndiceRootDir;
    struct stuFsDirectorioFAT stuFsFatDirentEntrada;

   iFnCargarFAT();
   vFnCargarRootDir();

    iIndiceFat = iFnBuscarEntradaFATLibre();
    vFnImprimir("\nCopiando en FAT: %d", iIndiceFat);

    iIndiceRootDir = iFnBuscarEntradaFATVacia();
    vFnImprimir("\tRoot Directory: %d", iIndiceRootDir);

    if(iIndiceFat==-1 || iIndiceRootDir==-1){
        return -1;
    }
    vFnConvierteNombreToFAT(pcNombre,stuFsFatDirentEntrada.filename);
    stuFsFatDirentEntrada.attributes=0x20;
    stuFsFatDirentEntrada.reserved=0;
    stuFsFatDirentEntrada.create_time=0;
    stuFsFatDirentEntrada.create_date=0;
    stuFsFatDirentEntrada.access_date=0;
    stuFsFatDirentEntrada.ea_index=0;
    stuFsFatDirentEntrada.modified_time=0;
    stuFsFatDirentEntrada.modified_date=0;
    stuFsFatDirentEntrada.starting_cluster=iIndiceFat;
    stuFsFatDirentEntrada.filesize=iFnObtenerTamanioArchivo(pcContArch);

    stuFsDirectorioFATRootDir[iIndiceRootDir]=stuFsFatDirentEntrada;


    vFnSetearEnFat(iIndiceFat,0xFFF);

    vFnRootDirToFloppy();
    vFnCopiaFatToFloppy();


    int iN, cant=0, caracteres=0;
    while(pcContArch[cant]!='\0')
 {
  stCadenaAux[cant]=pcContArch[cant];
  caracteres++;
         cant++;
 }
    for (iN = caracteres; iN < 512; iN++)
  stCadenaAux[iN]=' ';

    ucpFnCopiarMemoria((unsigned char*)byBufferRead, (unsigned char*)stCadenaAux, 512);
    escribirSector(byBufferRead, (((iIndiceFat-2)*1)+33));
    return 0;
}
# 1220 "fat.c"
int iFnObtenerTamanioArchivo(char * pcContArch)
{
     int iCantCaracteres=0;

 iFnCopiaCadena(stArgAux, pcContArch);

 while(stArgAux[iCantCaracteres]!='\0')
 {
   iCantCaracteres++;
 }

 iCantCaracteres++;

 if (iCantCaracteres < 128)
  return (iCantCaracteres);
 else
  return 512;
}







int iFnBuscarEntradaFATLibre(){
   int iN=0;
    for (iN=35;iN<=2848;iN++){
        if(uiFnBuscarNextSector(iN) == 0x00){
         return iN;
        }
    }
    return -1;
}






int iFnBuscarEntradaFATVacia(){
    int iN=0;
    for (iN=0;iN<224;iN++){
        if(stuFsDirectorioFATRootDir[iN].filename[0] == 0x00 || stuFsDirectorioFATRootDir[iN].filename[0] == 0xE5){
   return iN;
  }
    }
    return -1;
}





void vFnRootDirToFloppy(){
 int iN,iJ, iDesplazamiento=0;
 unsigned char * pRootDir=(unsigned char *)stuFsDirectorioFATRootDir;

 for(iN=0;iN<14;iN++){
                for(iJ=0;iJ<512;iJ++){
                    byBuffer[iJ] = pRootDir[iJ+iDesplazamiento];
                }
                escribirSector(byBuffer,iN+19);
                iDesplazamiento += 512;
        }
}





void vFnCopiaFatToFloppy(){
 int iN;
 char * pFat = pTablaFat1;

 for(iN=1;iN<=9;iN++){
    ucpFnCopiarMemoria((unsigned char*)byBuffer, (unsigned char*)pFat, 512 );
  escribirSector(byBuffer,iN);
  pFat+=512;
        }

 pFat=pTablaFat1;
 for(iN=1+9;iN<=9*2;iN++){
  ucpFnCopiarMemoria( (unsigned char*)byBuffer, (unsigned char*)pFat, 512 );
  escribirSector(byBuffer,iN);
  pFat+=512;
        }
}





void vFnCargarRootDir(){
 int iN,iJ=0,iK=0,iU,iIni=0,iFin=16,iOffset=0,iY;





        stuFsDirectorioFATRootDir = pvFnReservarParticionUsuario(224*32);


        for(iN=1;iN<=14;iN++){
                leerSector(byBuffer,iN+18);
  for(iY=iIni;iY<iFin;iY++){
                   if(iY>224){break;}
                   if((int)byBuffer[11+iOffset] != 15){
                      for(iU=0;iU<11;iU++){
                         stuFsDirectorioFATRootDir[iJ].filename[iU]=byBuffer[iK+iOffset];
                         iK++;
                      }
                      stuFsDirectorioFATRootDir[iJ].attributes = byBuffer[11+iOffset];
                stuFsDirectorioFATRootDir[iJ].reserved=(short)byBuffer[12+iOffset];
                      stuFsDirectorioFATRootDir[iJ].reserved|=(short)byBuffer[13+iOffset]<<8;
                      stuFsDirectorioFATRootDir[iJ].create_time=(short)byBuffer[14+iOffset];
                      stuFsDirectorioFATRootDir[iJ].create_time|=(short)byBuffer[15+iOffset]<<8;
                      stuFsDirectorioFATRootDir[iJ].create_date=(short)byBuffer[16+iOffset];
                      stuFsDirectorioFATRootDir[iJ].create_date|=(short)byBuffer[17+iOffset]<<8;
                      stuFsDirectorioFATRootDir[iJ].access_date=(short)byBuffer[18+iOffset];
                      stuFsDirectorioFATRootDir[iJ].access_date|=(short)byBuffer[19+iOffset]<<8;
                      stuFsDirectorioFATRootDir[iJ].ea_index=(short)byBuffer[20+iOffset];
                      stuFsDirectorioFATRootDir[iJ].ea_index|=(short)byBuffer[21+iOffset]<<8;
                      stuFsDirectorioFATRootDir[iJ].modified_time=(short)byBuffer[22+iOffset];
                      stuFsDirectorioFATRootDir[iJ].modified_time|=(short)byBuffer[23+iOffset]<<8;
                      stuFsDirectorioFATRootDir[iJ].modified_date=(short)byBuffer[24+iOffset];
                      stuFsDirectorioFATRootDir[iJ].modified_date|=(short)byBuffer[25+iOffset]<<8;
                      stuFsDirectorioFATRootDir[iJ].starting_cluster = (short)byBuffer[26+iOffset];
                      stuFsDirectorioFATRootDir[iJ].starting_cluster |= (short)byBuffer[27+iOffset] << 8;
                      stuFsDirectorioFATRootDir[iJ].filesize = (short)byBuffer[28+iOffset];
                      stuFsDirectorioFATRootDir[iJ].filesize |= (short)byBuffer[29+iOffset] << 8;
                      stuFsDirectorioFATRootDir[iJ].filesize |= (short)byBuffer[30+iOffset] << 16;
                      stuFsDirectorioFATRootDir[iJ].filesize |= (short)byBuffer[31+iOffset] << 24;
                     iJ++;
                     iK=0;
                   }
                   iOffset += 32;
                }
            iIni+=16;
            iFin+=16;
            iOffset=0;
        }
}







int iFnCargarFAT()
{
 unsigned short usTamnioFat=10*512;
 int iN,iJ;

 pTablaFat1 = pvFnReservarParticionUsuario(usTamnioFat);
 pTablaFat2 = pvFnReservarParticionUsuario(usTamnioFat);

 if(!pTablaFat1 || !pTablaFat2){
  vFnImprimir("Sin memoria para levantar la FAT\n");
  return -1;
        }

  for(iN=1+9;iN<=18;iN++){
  leerSector(byBuffer,iN);
    for(iJ=0;iJ<512;iJ++){
    pTablaFat2[iJ+((iN-(1+9))*512)]=byBuffer[iJ];
    }
  }

 for(iN=1;iN<=9;iN++){
  leerSector(byBuffer,iN);
  for(iJ=0;iJ<512;iJ++){
   pTablaFat1[iJ+((iN-1)*512)]=byBuffer[iJ];
    }
  }
 return 0;
}







unsigned int uiFnBuscarNextSector(unsigned int uiSector){
   return usFnObtenerSectorFat(uiSector);
}







void vFnSetearEnFat(unsigned short usSector,unsigned short usValor){

        unsigned char ucAux = 0;
        unsigned char ucAux2 = 0;

        if(usSector%2==0){


           ucAux=(unsigned char)pTablaFat1[((6*usSector)/4)+1] & 0xF0;

           ucAux2=(unsigned char) usValor>>8;
           ucAux|=ucAux2;
           pTablaFat1[((6*usSector)/4)+1]=ucAux;


     ucAux=(unsigned char) usValor && 0x00FF;
     pTablaFat1[(6*usSector)/4]=ucAux;
        }
     else{
           ucAux=(unsigned char)pTablaFat1[(6*usSector)/4] & 0x00F0;

         ucAux2=(unsigned char) usValor && 0x000F;
         ucAux|=ucAux2;

         ucAux=(unsigned char)usValor>>4;
         pTablaFat1[((6*usSector)/4)+1]=ucAux;
        }
}







unsigned short usFnObtenerSectorFat(unsigned short usSector){

        unsigned short usAux = 0;

        if(usSector%2==0){
           usAux=(unsigned short)pTablaFat1[((6*usSector)/4)+1] & 0x000F;
           usAux=usAux<<8;
           usAux|=(unsigned short)pTablaFat1[(6*usSector)/4];
        }
        else{
           usAux=(unsigned short)pTablaFat1[(6*usSector)/4] & 0x00F0;
           usAux=usAux>>4;
           usAux|=((unsigned short)pTablaFat1[((6*usSector)/4)+1])<<4;
        }
        return (unsigned short) usAux;
}
# 1493 "fat.c"
void vFnConvierteNombreToFAT(char *pcNombre, char *pucNombreAdaptado){
     int iZ,iPunto=0,iX=0;
     vFnStrUpr(pcNombre);
     for(iZ=0;iZ<11;iZ++){
        if(pcNombre[iX]=='.'){
            iPunto=1;
            iX++;
        }
        if((iZ<8 && iPunto==1) || pcNombre[iX]=='\0'){
            pucNombreAdaptado[iZ]=' ';
        }
        else{
            pucNombreAdaptado[iZ]=pcNombre[iX];
            iX++;
        }
     }
}



void imprimirTablaFAT( char *pcFat )
{
 byte byLsb, byMsb;
 word wSector=1, wSigSector;

 int iN;
 byte *pbyP=(byte*)pcFat;

 vFnImprimir( "\nImprimiendo Tabla FAT \n");
 for( iN=0; iN<(512*9); iN++ );
 {
  vFnImprimir( "%xb", *pbyP++ );
  if ((iN%3)==0)
   vFnImprimir( "\t" );
 }
 vFnImprimir( "\nFAT ha sido impresa\n" );


 pbyP = (byte *)pcFat;
 for( iN=0; iN<(512*9); iN+=2 );
 {
  byLsb = *pbyP++;
  byMsb = *pbyP++;

  if( wSector % 2)
   wSigSector = (((byMsb << 8 ) | byLsb)& 0xfff0 ) >> 4;
  else
   wSigSector = (( byMsb << 8 ) | byLsb) & 0x0fff ;
  wSector++;
  vFnImprimir( ":%d\t", wSigSector );
 }
 cFnGetChar();

}

int TEST_WRITE_READ()
{
    vFnImprimir("Inicio TEST_WRITE_READ()");
    vFnImprimir ("\n[s]salir]>"); if( cFnGetChar() == 's') return(1);;
    byte byAux;
    int iN;
    byAux = 0xab;
    for (iN = 0; iN < 512; iN++)
 byBufferRead[iN] = byAux;
    escribirSector(byBufferRead, 1000);
    leerSector(byBuffer,1000);
    for (iN = 0; iN < 512; iN++)
 vFnImprimir("%iX",byBuffer[iN]);
 return 1;
}

void TEST_BUSCA_FAT()
{
 int iN=0,iJ=0;
 for (iN=35;iN<=2848;iN++){
  if(uiFnBuscarNextSector(iN) == 0x00){
  iJ++;
  }
 }

 vFnImprimir("Entradas Vacias: %d",iJ);
}
